#ifndef _OBJECTRUN_H_
#define _OBJECTRUN_H_

#include "stdafx.h"
#include "plugins.h"

class CObjectRunImpl : public IObjectRun, public IMsgPlugin, public CUnknownImp
{
public:
    CObjectRunImpl();
    virtual ~CObjectRunImpl(void);

    BEGIN_STDCOM_MAP
    STDCOM_INTERFACE_ENTRY_UNKNOWN_(IObjectRun)
    STDCOM_INTERFACE_ENTRY(IObjectRun)
    STDCOM_INTERFACE_ENTRY(IMsgPlugin)
    END_STDCOM_MAP

public:
    // IObjectRun
    std_method(SetMainRun)(IBase* pBase);
    std_method(SetClsid)(REFCLSID clsid);
    std_method_(CLSID, GetClsid)();
    std_method(LoadConf)(const SafeStringPtr* code);
    std_method_(LPCSTR, GetConf)();
    std_method(Register)(SafeStringConstPtr name, UINT type, UINT version);
    std_method(UnRegister)(SafeStringConstPtr name, UINT type, UINT version);
    std_method(Registers)(UINT type, UINT version);
    std_method(UnRegisters)(UINT type, UINT version);
    std_method(SetPath)(const SafePStringPtr* path);
    std_method_(LPSTRING, GetPath)();
    std_method(Load)();
    std_method(Init)(_pid_t pid, basic_tchar* argv[], int argc);
    std_method(Start)(UINT type);
    std_method(Stop)(UINT type, UINT exit);
    std_method_(UINT, Run)(UINT type);
    std_method(Exit)(UINT exit);
    std_method(Uninit)();
    std_method(Clear)();
    std_method(GetRotPlugin)(IBase** pBase);
    std_method(GetMsgPlugin)(IBase** pBase);
    std_method(GetLoaderPlugin)(IBase** pBase);
    std_method(GetMainRunPlugin)(IBase** pBase);
    std_method(AddObject)(REFCLSID clsid, LPCSTR progid, IBase* pBase, ULONG index, LPCSTR container, UINT type);
    std_method_(CLSID, GetRunPluginCLSID)();
    std_method_(ULONG, GetRunPluginsCount)();
    std_method_(ULONG, GetRunIndex)(ULONG index);
    std_method_(UINT, GetExitCode)();
    std_method_(UINT, GetArgc)();
    std_method_(LPSTRING, GetIndexArgc)(UINT index);
    std_method_(UINT, GetStartType)();
    std_method_(_pid_t, get_instance)();

    // IMsgPlugin
    std_method(OnMsgStart)();
    std_method(OnMsgStop)();
    std_method(OnMsgSend)(CLSID sn, CLSID tn, UINT msg, IBase* inmsg, IBase** outmsg);
    std_method(OnMsgRecv)(CLSID sn, CLSID tn, UINT msg, IBase* inmsg, IBase** outmsg);
    std_method_(ULONG, GetRoute)();
    std_method_(ULONG, GetSub)();
    std_method(Set)(ULONG ad);

private:
    std_method(SetRunArgc)(int argc, basic_tchar* argv[]);
    std_method(LoadRunConf)(LPCSTR buf, ULONG len);
    std_method(LoadBasePlugin)();
    std_method(LoadPlugins)();
    std_method(LoadContainers)();
    std_method(LoadContainer)(LPCSTR name);
    std_method(FreeContainer)(LPCSTR name);

private:
    std_method(CreatePlugin)(REFCLSID clsid, UINT index);
    std_method(UninitAllPlugins)();
    std_method(CreateRotPlugin)(REFCLSID clsid, IBase** plugin, UINT index);
    std_method(DestroyAllRotPlugin)();
    std_method(DestroyRotPlugin)(REFCLSID clsid);
    std_method(SendMessage)(CLSID sn, CLSID tn, UINT msg, IBase* inmsg, IBase** outmsg);

private:
    std_method_(UINT, DoPluginsRun)(UINT uType);
    std_method(DoPluginsStartFunc)(UINT uType);
    std_method(DoPluginsStopFunc)(UINT uType, UINT uExit);
    std_method_(UINT, GetIExitCode)(CLSID iid);

private:
    std_method(RunPlugin_Start)(BaseConstPtr pBase, UINT type);
    std_method(RunPlugin_Stop)(BaseConstPtr pBase, UINT exit);
    std_method(RunStdPlugin_Start)(BaseConstPtr pBase, UINT type);
    std_method(RunStdPlugin_Stop)(BaseConstPtr pBase, UINT exit);
    std_method(RunMsgPlugin_Start)(BaseConstPtr pBase);
    std_method(RunMsgPlugin_Stop)(BaseConstPtr pBase);
    std_method(RunMsgPlugin_Recv)(BaseConstPtr pBase, REFCLSID sn, REFCLSID tn, UINT msg, IBase* inmsg, IBase** outmsg);

private:
    std_method(Reset)();
    std_method_(path_string, ContainerPath)(LPCSTR ComponentName);

private:
    MainRunPtr m_pIMainRun;
    RotPtr m_pIRot;
    LibManagerPtr m_pILibManager;

private:
    path_string m_strRunPath;
    string m_strRegisterCode;

private:
    CPlugins m_Plugins;
    PluginVector m_PluginsClsid;
    CLSID m_RunPlugin;
    path_string m_strContainer;
    basic_tchar** m_argv;
    UINT m_argc;

private:
    CLSID m_strObjectClsid;
    UINT m_type;
    _pid_t m_pid;
    UINT m_exitcode;
};

#endif
